/**
  * Author: Mei
  * Date: 2021-01-07 15:54
  * Description: ioc容器
  *
  */
#include "../head.h"

template<class T> //T是一个接口
class IocContainer {
public:
    IocContainer(void) {
    }

    ~IocContainer() {
    }

    //注册需要创建对象的构造函数，需要传入一个唯一的标识，以便在后面查找
    template<class Derived, typename ...Args>
    void RegisterType(string strKey, Args &&...args) {
        function<T *()> func = [args...]() {
            return new Derived(args...);
        };
        RegisterType(strKey, func);
    }

    //根据标识去查找对应的构造器，并创建对象
    T *Resolve(string strKey) {
        if (m_creatorMap.find(strKey) == m_creatorMap.end()) {
            return nullptr;
        }
        function<T *()> func = m_creatorMap[strKey];
        return func(); //执行lambda表达式 创建对象
    }

    //创建智能智能对象
    shared_ptr<T> ResolvedShared(string strKey) {
        T *ptr = Resolve(strKey);
        return shared_ptr<T>(ptr);
    }

private:
    void RegisterType(string key, function<T *()> creator) {
        if (m_creatorMap.find(key) != m_creatorMap.end()) {
            throw invalid_argument("this key has already exist！");
        }
        m_creatorMap.emplace(key, creator);
    }

private:
    map<string, function<T *()>> m_creatorMap;

};

//测试类
struct ICar {
    virtual ~ICar() {}

    virtual void test() const = 0;
};

struct Bus : ICar {
    Bus(int i, int j) {
        cout << "value i = " << i << ", j=" << j << endl;
    }

    void test() const {
        cout << "Bus::test()" << endl;
    }
};

struct Car : ICar {
    Car() {}

    void test() const {
        cout << "Car::test()" << endl;
    }
};

int main() {
    //测试
    IocContainer<ICar> carioc;
    carioc.RegisterType<Bus>("bus", 10, 20);
    carioc.RegisterType<Car>("car");
    shared_ptr<ICar> bus = carioc.ResolvedShared("bus");
    bus->test();
    shared_ptr<ICar> car = carioc.ResolvedShared("car");
    car->test();

    //不足的是只能创建一种接口类型的对象，不能创建所有类型的对象，可以通过类型擦除技术来实现


    return 0;
}
